package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.pojo.UserInfo;
import com.itheima.service.UserInfoService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@Aspect
public class OpLogSaveAspect {

    @Reference
    UserInfoService userInfoService;


    //@Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RestController) ")
    @Pointcut("execution(* com.itheima.controller.*.*(..))")
    public void operationLog() {

    }


    @Around(value = "operationLog()")
    public Object aroundService(ProceedingJoinPoint pjp) throws Throwable {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        Signature signature = pjp.getSignature();

        MethodSignature methodSignature = (MethodSignature)signature;

        Method targetMethod = methodSignature.getMethod();
        String methodName = targetMethod.getName();//方法
        String username = user.getUsername(); //姓名

        String userip = request.getRemoteAddr();
        RequestMapping annotation = targetMethod.getAnnotation(RequestMapping.class);

//        Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
        Object obj;
        try {
            Object[] args = pjp.getArgs(); // 请求接收的参数args
            Date currentTime = new Date();
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //操作时间
            String date = formatter.format(currentTime);
            System.out.println(date);
            System.out.println("方法"+methodName);
            System.out.println("注解"+annotation);
            System.out.println("名字"+username);
            UserInfo userInfo = new UserInfo();
            userInfo.setUsername(username);
            userInfo.setMethodName(methodName);
            userInfo.setDate(date);
            userInfo.setUserip(userip);
            //存入数据库
            userInfoService.add(userInfo);


            obj = pjp.proceed();
        } catch (Throwable t) {
            throw t;
        }

        System.out.println("obj"+obj);
        return obj;

    }


}







//package com.itheima.aop;
//import com.alibaba.dubbo.config.annotation.Reference;
////import com.itheima.pojo.Log;
////import com.itheima.service.OpLogSaveService;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.Signature;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.security.core.userdetails.User;
//import org.springframework.stereotype.Component;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.lang.reflect.Method;
//import java.text.SimpleDateFormat;
//import java.util.Date;
//
//@Component
//@Aspect
//public class OpLogSaveAspect {
//    //@Reference
//    //OpLogSaveService logSaveService;
//
//    //    @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RestController) ")
//    //切点表达式 com.itheima.web，所有的类下的所有的方法
//    //    @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RestController) ")
//    @Pointcut("execution(* com.itheima.controller.*.*(..))")
//    public void operationLog() {
//    }
//
//    @Around(value = "operationLog()")
//    public Object aroundService(ProceedingJoinPoint pjp) throws Throwable {
//        //获取登录用户的信息
//        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//
//        //转化request 方便拿东西
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//        Signature signature = pjp.getSignature();
////        String methods = signature.getName();
////        System.out.println("当前方法"+methods);
//        //从切面织入点处通过反射机制获取织入点处的方
//        MethodSignature methodSignature = (MethodSignature)signature;
//        //获取切入点所在的方法
//        Method targetMethod = methodSignature.getMethod();
//        String methodName = targetMethod.getName();
////        System.out.println("切入方法"+targetMethod);
//        //获取方法上的注解
//        RequestMapping annotation = targetMethod.getAnnotation(RequestMapping.class);
//        System.out.println("注解"+annotation);
//
////        Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
//        Object obj;
//        try {
//            Object[] args = pjp.getArgs(); // 请求接收的参数args
//            Date currentTime = new Date();
//            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            //操作时间
//            String date = formatter.format(currentTime);
////            System.out.println(date);
//
////
////            System.out.println(date);
//            //执行原有方法
//            obj = pjp.proceed();
//            String username = user.getUsername();
////            System.out.println(username);
//            //Log log =new Log();
//            //log.setTargetMethod(methodName);
//            System.out.println(methodName);
//            //log.setDate(date);
//            System.out.println(date);
//            //log.setUserName(username);
////            logSaveService.save(log);
//        } catch (Throwable t) {
//            throw t;
//        }
//        //
//        return obj;
//
//    }
//
//
//}
